#include "face_api.h"

#if (_SAFETY_MODULE_TYPE_ == _FACE_SAFETY_MODULE_) && (_SAFETY_VERIFYFUNCTION_ENABLE_)
#if (_FACE_MODULE_TYPE_ == _AIVA_FACE_MODEL_)
uint8_t FaceParityCheck(uint8_t *pDataIn, uint16_t DataSize)
{
  uint8_t CheckCode = pDataIn[0];

  for (uint16_t i = 1; i < DataSize; i++)
  {
    CheckCode ^= pDataIn[i];
  }

  return CheckCode;
}

bool FaceBuildSoftwareResetMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_RESET_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetModuleStatusMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_STATUS_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildStartVerifyMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t Timeout)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_VERIFY_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = (uint8_t)((Timeout & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(Timeout & 0x00FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildStartNewUserRegistrationMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, bool Admin, uint8_t *pUserNameIn, uint8_t Timeout, uint8_t Direction)
{
  bool BuildResult = false;
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    switch (Direction)
    {
    case FACE_DIRECTION_UNDEFINE:
    case FACE_DIRECTION_MIDDLE:
    case FACE_DIRECTION_RIGHT:
    case FACE_DIRECTION_LEFT:
    case FACE_DIRECTION_DOWN:
    case FACE_DIRECTION_UP:
    {
      BuildResult = true;

      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_ENROLL_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = FACE_MAX_USER_NAME_LENGTH + 3;
      pMessageOut[MessageSize++] = Admin;
      (pUserNameIn != NULL) ? memcpy(&pMessageOut[MessageSize], pUserNameIn, FACE_MAX_USER_NAME_LENGTH) : memset(&pMessageOut[MessageSize], 0, FACE_MAX_USER_NAME_LENGTH);
      MessageSize += FACE_MAX_USER_NAME_LENGTH;
      pMessageOut[MessageSize++] = Direction;
      pMessageOut[MessageSize++] = Timeout;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
    }
    break;
    }
  }

  return BuildResult;
}

bool FaceBuildGetPictureSizeMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_CAPTURE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildCapturePictureMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t Counts, uint8_t StartNumber)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (StartNumber >= 1) && (StartNumber <= 30))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SNAP_IMAGE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = Counts;
    pMessageOut[MessageSize++] = StartNumber;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetCapturedPicturesMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t NumberOfPictures)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (NumberOfPictures >= 1) && (NumberOfPictures <= 30))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_SAVED_IMAGE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x01;
    pMessageOut[MessageSize++] = NumberOfPictures;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildUploadImageMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t ImageOffset, uint32_t ImageSize)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (ImageSize != 0) && (ImageSize <= FACE_MAX_FILE_REQUEST_SIZE))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_UOLOAD_IMAGE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x08;
    pMessageOut[MessageSize++] = (uint8_t)((ImageOffset & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((ImageOffset & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((ImageOffset & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(ImageOffset & 0x000000FF);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(ImageSize & 0x000000FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildExampleDeleteSpecifiedUserMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t UserId)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_DEL_USER_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = (uint8_t)((UserId & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(UserId & 0x00FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildDeleteAllUserMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_DEL_ALL_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetUserInformationMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t UserId)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_USER_INFO_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = (uint8_t)((UserId & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(UserId & 0x00FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildResetAlgorithmStateMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_FACE_RESET_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetAllUserIdMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_ALL_USER_ID_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildEnrollItgMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, bool Admin, uint8_t *pUserNameIn, bool EnrollType, bool EnableDuplicate, uint8_t TimeOut, uint8_t Direction)
{
  uint16_t MessageSize = 0;

  switch (Direction)
  {
  case FACE_DIRECTION_UNDEFINE:
  case FACE_DIRECTION_MIDDLE:
  case FACE_DIRECTION_RIGHT:
  case FACE_DIRECTION_LEFT:
  case FACE_DIRECTION_DOWN:
  case FACE_DIRECTION_UP:
  {
    if ((pMessageOut != NULL) && (pSizeOut != NULL))
    {
      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_ENROLL_ITG_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = FACE_MAX_USER_NAME_LENGTH + 8;
      pMessageOut[MessageSize++] = Admin;
      (pUserNameIn != NULL) ? memcpy(&pMessageOut[MessageSize], pUserNameIn, FACE_MAX_USER_NAME_LENGTH) : memset(&pMessageOut[MessageSize], 0, FACE_MAX_USER_NAME_LENGTH);
      MessageSize += FACE_MAX_USER_NAME_LENGTH;
      pMessageOut[MessageSize++] = Direction;
      pMessageOut[MessageSize++] = EnrollType;
      pMessageOut[MessageSize++] = EnableDuplicate;
      pMessageOut[MessageSize++] = TimeOut;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
      return true;
    }
  }
  break;
  }

  return false;
}

bool FaceBuildGetModuleVersionMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_VERSION_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetModuleSnMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_SN_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildInitEncryptioMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t Random, uint8_t Mode, uint32_t CurrentTime)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_INIT_ENCRYPTION_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x09;
    pMessageOut[MessageSize++] = (uint8_t)((Random & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((Random & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((Random & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(Random & 0x000000FF);
    pMessageOut[MessageSize++] = Mode;
    pMessageOut[MessageSize++] = (uint8_t)((CurrentTime & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((CurrentTime & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((CurrentTime & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(CurrentTime & 0x000000FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildConfigUartBandrateMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t BaudRate)
{
  bool BuildResult = false;
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    switch (BaudRate)
    {
    case FACE_UART_BAUDRATE_115200:
    case FACE_UART_BAUDRATE_230400:
    case FACE_UART_BAUDRATE_460800:
    case FACE_UART_BAUDRATE_1500000:
    {
      BuildResult = true;

      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_CONFIG_BAUDRATE_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = 0x01;
      pMessageOut[MessageSize++] = BaudRate;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
    }
    break;
    }
  }

  return BuildResult;
}

bool FaceBuildSetReleaseEncryptioKeyMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t *pEncryptioKeyIn)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (pEncryptioKeyIn != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SET_RELEASE_ENC_KEY_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FACE_ENCRYPTION_KEY_LENGTH;
    memcpy(&pMessageOut[MessageSize], pEncryptioKeyIn, FACE_ENCRYPTION_KEY_LENGTH);
    MessageSize += FACE_ENCRYPTION_KEY_LENGTH;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildSetDebugReleaseEncryptioKeyMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t *pEncryptioKeyIn)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (pEncryptioKeyIn != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SET_DEBUG_ENC_KEY_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FACE_ENCRYPTION_KEY_LENGTH;
    memcpy(&pMessageOut[MessageSize], pEncryptioKeyIn, FACE_ENCRYPTION_KEY_LENGTH);
    MessageSize += FACE_ENCRYPTION_KEY_LENGTH;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildSetThresholdLevelMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t Liveness, uint8_t Verify)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (Liveness < 4) && (Verify < 4))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SET_THRESHOLD_LEVEL_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = Liveness;
    pMessageOut[MessageSize++] = Verify;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildModulePowerDownMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_POWER_DOWN_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildIntoDemoModeMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_DEMO_MODE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildTransFilePacketMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t SizeOfFile, uint32_t Offset, uint16_t SizeOfPacket, uint8_t *pPacketFileIn)
{
  uint16_t MessageSize = 0, PacketSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    if (SizeOfPacket <= FACE_MAX_FILE_REQUEST_SIZE)
    {
      PacketSize = SizeOfPacket + 11;

      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_TRANS_FILE_PACKET_CMD;
      pMessageOut[MessageSize++] = (uint8_t)((PacketSize & 0xFF00) >> 8);
      pMessageOut[MessageSize++] = (uint8_t)(PacketSize & 0x00FF);
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = (uint8_t)((SizeOfFile & 0xFF000000) >> 24);
      pMessageOut[MessageSize++] = (uint8_t)((SizeOfFile & 0x00FF0000) >> 16);
      pMessageOut[MessageSize++] = (uint8_t)((SizeOfFile & 0x0000FF00) >> 8);
      pMessageOut[MessageSize++] = (uint8_t)(SizeOfFile & 0x000000FF);
      pMessageOut[MessageSize++] = (uint8_t)((Offset & 0xFF000000) >> 24);
      pMessageOut[MessageSize++] = (uint8_t)((Offset & 0x00FF0000) >> 16);
      pMessageOut[MessageSize++] = (uint8_t)((Offset & 0x0000FF00) >> 8);
      pMessageOut[MessageSize++] = (uint8_t)(Offset & 0x000000FF);
      pMessageOut[MessageSize++] = (uint8_t)((SizeOfPacket & 0xFF00) >> 8);
      pMessageOut[MessageSize++] = (uint8_t)(SizeOfPacket & 0x00FF);
      memcpy(&pMessageOut[MessageSize], pPacketFileIn, SizeOfPacket);
      MessageSize += SizeOfPacket;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
      return true;
    }
  }

  return false;
}

bool FaceBuildEnrollFromImageMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, bool Admin, uint8_t *pUserNameOut, bool ImageType, uint8_t Timeout)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_ENROLL_FROM_IMAGE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FACE_MAX_USER_NAME_LENGTH + 3;
    pMessageOut[MessageSize++] = Admin;
    (pUserNameOut != NULL) ? memcpy(&pMessageOut[MessageSize], pUserNameOut, FACE_MAX_USER_NAME_LENGTH) : memset(&pMessageOut[MessageSize], 0, FACE_MAX_USER_NAME_LENGTH);
    MessageSize += FACE_MAX_USER_NAME_LENGTH;
    pMessageOut[MessageSize++] = ImageType;
    pMessageOut[MessageSize++] = Timeout;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetFeatureInformatizationMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t UserId)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_FEATURE_INFO_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = (uint8_t)((UserId & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(UserId & 0x00FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildUploadFeatureDataMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t FeatureOffset, uint32_t SizeOfFeature)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_UPLOAD_FEATURE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x08;
    pMessageOut[MessageSize++] = (uint8_t)((FeatureOffset & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((FeatureOffset & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((FeatureOffset & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(FeatureOffset & 0x00000FF);
    pMessageOut[MessageSize++] = (uint8_t)((SizeOfFeature & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((SizeOfFeature & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((SizeOfFeature & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(SizeOfFeature & 0x00000FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildEnrollFromFeatureMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, bool Admin, uint8_t *pUserNameIn, uint8_t Direction, uint8_t Timeout)
{
  bool BuildResult = false;
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    switch (Direction)
    {
    case FACE_DIRECTION_UNDEFINE:
    case FACE_DIRECTION_MIDDLE:
    case FACE_DIRECTION_RIGHT:
    case FACE_DIRECTION_LEFT:
    case FACE_DIRECTION_DOWN:
    case FACE_DIRECTION_UP:
    {
      BuildResult = true;

      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_ENROLL_WITH_FEATURE_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = FACE_MAX_USER_NAME_LENGTH + 3;
      pMessageOut[MessageSize++] = Admin;
      (pUserNameIn != NULL) ? memcpy(&pMessageOut[MessageSize], pUserNameIn, FACE_MAX_USER_NAME_LENGTH) : memset(&pMessageOut[MessageSize], 0, FACE_MAX_USER_NAME_LENGTH);
      MessageSize += FACE_MAX_USER_NAME_LENGTH;
      pMessageOut[MessageSize++] = Direction;
      pMessageOut[MessageSize++] = Timeout;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
    }
    break;
    }
  }

  return BuildResult;
}

bool FaceBuildCapturePictureTypeMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t Width, uint16_t Height, bool CaptureType, uint8_t CompressRatio, bool CutoutFace)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    if ((CompressRatio == 0x06) || (CompressRatio == 0x08) || (CompressRatio == 0x0B))
    {
      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_CAPTURE_PIC_TYPE_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = 0x07;
      pMessageOut[MessageSize++] = (uint8_t)((Width & 0xFF00) >> 8);
      pMessageOut[MessageSize++] = (uint8_t)(Width & 0x00FF);
      pMessageOut[MessageSize++] = (uint8_t)((Height & 0xFF00) >> 8);
      pMessageOut[MessageSize++] = (uint8_t)(Height & 0x00FF);
      pMessageOut[MessageSize++] = CaptureType;
      pMessageOut[MessageSize++] = CompressRatio;
      pMessageOut[MessageSize++] = CutoutFace;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
      return true;
    }
  }

  return false;
}

bool FaceBuildGetsNumberOfAllRegisteredUsersMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;
  uint8_t XorParityCode = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_MX_GET_ALL_USERID_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildEnrollSingleMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, bool Admin, uint8_t *pUserNameIn, uint8_t Timeout, uint8_t Direction)
{
  bool BuildResult = false;
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    switch (Direction)
    {
    case FACE_DIRECTION_UNDEFINE:
    case FACE_DIRECTION_MIDDLE:
    case FACE_DIRECTION_RIGHT:
    case FACE_DIRECTION_LEFT:
    case FACE_DIRECTION_DOWN:
    case FACE_DIRECTION_UP:
    {
      BuildResult = true;

      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_ENROLL_SINGLE_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = FACE_MAX_USER_NAME_LENGTH + 3;
      pMessageOut[MessageSize++] = Admin;
      (pUserNameIn != NULL) ? memcpy(&pMessageOut[MessageSize], pUserNameIn, FACE_MAX_USER_NAME_LENGTH) : memset(&pMessageOut[MessageSize], 0, FACE_MAX_USER_NAME_LENGTH);
      MessageSize += FACE_MAX_USER_NAME_LENGTH;
      pMessageOut[MessageSize++] = Direction;
      pMessageOut[MessageSize++] = Timeout;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
    }
    break;
    }
  }

  return BuildResult;
}

bool FaceBuildGetAlgorithmVersion(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_ALGORITHM_VERSION;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceParesNotificationsMessage(const uint8_t *pMessageIn, uint8_t *pEventTypeOut)
{
  FaceNoteProtocolFormat_t *pNoteProtocolFormat = (FaceNoteProtocolFormat_t *)pMessageIn;

  if (pNoteProtocolFormat != NULL)
  {
    if (pEventTypeOut != NULL)
    {
      *pEventTypeOut = pNoteProtocolFormat->NoteMessageId;
    }

    return true;
  }

  return false;
}

bool FaceReplySoftwareResetMessage(const uint8_t *pMessageIn)
{
  return true;
}

bool FaceReplyGetModuleStatusMessage(const uint8_t *pMessageIn, uint8_t *pCurrentStateOut)
{
  bool ReplyStatus = false;

  if (pMessageIn != NULL)
  {
    switch (pMessageIn[0])
    {
    case MODULE_IDLE:
    case MODULE_BUSY:
    case MODULE_ERROR:
    case MODULE_INVALID:
    {
      if (pCurrentStateOut != NULL)
      {
        *pCurrentStateOut = pMessageIn[0];
      }

      pMessageIn++;
      ReplyStatus = true;
    }
    break;
    }
  }

  return ReplyStatus;
}

bool FaceReplyVerifyMessage(const uint8_t *pMessageIn, uint16_t *pUserIdOut, uint8_t *pUserNameOut, uint8_t *pAdminOut, uint8_t *pUnlockStateOut)
{
  if (pMessageIn != NULL)
  {
    if (pUserIdOut != NULL)
    {
      *pUserIdOut = (pMessageIn[0] << 8) | pMessageIn[1];
    }

    pMessageIn += 2;
    if (pUserNameOut != NULL)
    {
      memcpy(pUserNameOut, pMessageIn, FACE_MAX_USER_NAME_LENGTH);
    }

    pMessageIn += FACE_MAX_USER_NAME_LENGTH;
    if (pAdminOut != NULL)
    {
      *pAdminOut = *pMessageIn;
    }

    pMessageIn++;
    if (pUnlockStateOut != NULL)
    {
      *pUnlockStateOut = *pMessageIn;
    }

    pMessageIn++;
    return true;
  }

  return false;
}

bool FaceReplyStartNewUserRegistrationMessage(const uint8_t *pMessageIn, uint16_t *pUserIdOut, uint8_t *pDirectionOut)
{
  if (pMessageIn != NULL)
  {
    if (pUserIdOut != NULL)
    {
      *pUserIdOut = pMessageIn[0] << 8;
      *pUserIdOut |= pMessageIn[1];
    }

    pMessageIn += 2;
    if (pDirectionOut != NULL)
    {
      *pDirectionOut = *pMessageIn;
    }

    pMessageIn++;
    return true;
  }

  return false;
}

bool FaceReplyCaptureMessage(const uint8_t *pMessageIn, uint32_t *pImageSizeOut)
{
  if (pMessageIn != NULL)
  {
    if (pImageSizeOut != NULL)
    {
      *pImageSizeOut = pMessageIn[0] << 24;
      *pImageSizeOut |= pMessageIn[1] << 16;
      *pImageSizeOut |= pMessageIn[2] << 8;
      *pImageSizeOut |= pMessageIn[3];
    }

    pMessageIn += 4;
    return true;
  }

  return false;
}

bool FaceReplySnapImageMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplyGetSavedImageMessage(const uint8_t *pMessageIn, uint32_t *pImageSizeOut)
{
  if (pMessageIn != NULL)
  {
    if (pImageSizeOut != NULL)
    {
      *pImageSizeOut = pMessageIn[0] << 24;
      *pImageSizeOut |= pMessageIn[1] << 16;
      *pImageSizeOut |= pMessageIn[2] << 8;
      *pImageSizeOut |= pMessageIn[3];
    }

    pMessageIn += 4;
    return true;
  }

  return false;
}

bool FaceReplyUploadImageMessage(const uint8_t *pMessageIn, uint32_t *pImageOffset, uint32_t *pImageSizeOut)
{
  uint32_t ImageOffset = 0, ImageSize = 0;

  if (pMessageIn != NULL)
  {
    if (pImageOffset != NULL)
    {
      ImageOffset = pMessageIn[0] << 24;
      ImageOffset |= pMessageIn[1] << 16;
      ImageOffset |= pMessageIn[2] << 8;
      ImageOffset |= pMessageIn[3];

      *pImageOffset = ImageOffset;
    }

    pMessageIn += 4;
    if (pImageSizeOut != NULL)
    {
      ImageSize = pMessageIn[0] << 24;
      ImageSize |= pMessageIn[1] << 16;
      ImageSize |= pMessageIn[2] << 8;
      ImageSize |= pMessageIn[3];

      *pImageSizeOut = ImageSize;
    }

    pMessageIn += 4;
    return true;
  }

  return false;
}

bool FaceReplyExampleDeleteSpecifiedUserMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplyDeleteAllUserMessage(const uint8_t *pMessageIn)
{
  return true;
}

bool FaceReplyGetUserInformationMessage(const uint8_t *pMessageIn, uint16_t *pUserIdOut, uint8_t *pUserNameOut, uint8_t *pAdmin)
{
  if (pMessageIn != NULL)
  {
    if (pUserIdOut != NULL)
    {
      *pUserIdOut = pMessageIn[0] << 8;
      *pUserIdOut |= pMessageIn[1];
    }

    pMessageIn += 2;
    if (pUserNameOut != NULL)
    {
      memcpy(pUserNameOut, pMessageIn, FACE_MAX_USER_NAME_LENGTH);
    }

    pMessageIn += FACE_MAX_USER_NAME_LENGTH;
    if (pAdmin != NULL)
    {
      *pAdmin = *pMessageIn;
    }

    pMessageIn++;
    return true;
  }

  return false;
}

bool FaceReplyResetAlgorithmStateMessage(const uint8_t *pMessageIn)
{
  return true;
}

bool FaceReplyGetAllUserIdMessage(const uint8_t *pMessageIn, uint8_t *pNumberOfUserOut, uint16_t *pUserIdOut)
{
  uint8_t NumberOfUser = 0;
  uint16_t MessageOffset = 0;

  if (pMessageIn != NULL)
  {
    NumberOfUser = pMessageIn[MessageOffset++];
    if (pNumberOfUserOut != NULL)
    {
      *pNumberOfUserOut = NumberOfUser;
    }

    if (pUserIdOut != NULL)
    {
      if (NumberOfUser <= FACE_NUMBER_OF_REGISTERED_USERS)
      {
        for (uint8_t i = 0; i < NumberOfUser; i++)
        {
          pUserIdOut[i] = pMessageIn[MessageOffset++] << 8;
          pUserIdOut[i] |= pMessageIn[MessageOffset++];
        }
      }
    }

    return true;
  }

  return false;
}

bool FaceReplyEnrollItgMessage(const uint8_t *pMessageIn, uint16_t *pUserIdOut, uint8_t *pDirection)
{
  if (pMessageIn != NULL)
  {
    if (pUserIdOut != NULL)
    {
      *pUserIdOut = pMessageIn[0] << 8;
      *pUserIdOut |= pMessageIn[1];
    }

    pMessageIn += 2;
    if (pDirection != NULL)
    {
      *pDirection = *pMessageIn;
    }

    pMessageIn++;
    return true;
  }

  return false;
}

bool FaceReplyGetModuleVersionMessage(const uint8_t *pMessageIn, uint8_t *pVersionOut)
{
  if (pMessageIn != NULL)
  {
    if (pVersionOut != NULL)
    {
      memcpy(pVersionOut, pMessageIn, FACE_LENGTH_OF_VERSION_INFORMATION);
    }

    pMessageIn += FACE_LENGTH_OF_VERSION_INFORMATION;
    return true;
  }

  return false;
}

bool FaceReplyGetModuleSnMessage(const uint8_t *pMessageIn, char *pSnNumberOut)
{
  if (pMessageIn != NULL)
  {
    if (pSnNumberOut != NULL)
    {
      memcpy(pSnNumberOut, pMessageIn, FACE_MODULE_SN_LENGTH);
    }

    pMessageIn += FACE_MODULE_SN_LENGTH;
    return true;
  }

  return false;
}

bool FaceReplyInitEncryptioMessage(const uint8_t *pMessageIn, uint8_t *pDeviceIdOut)
{
  if (pMessageIn != NULL)
  {
    if (pDeviceIdOut != NULL)
    {
      memcpy(pDeviceIdOut, pMessageIn, 20);
    }

    pMessageIn += 20;
    return true;
  }

  return false;
}

bool FaceReplyConfigUartBandrateMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplySetReleaseEncryptioKeyMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplySetDebugEncryptioKeyMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplyTransFilePacketMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplyEnrollFromImageMessage(const uint8_t *pMessageIn, uint16_t *pUserIdOut, uint8_t *pDirection)
{
  if (pMessageIn != NULL)
  {
    if (pUserIdOut != NULL)
    {
      *pUserIdOut = pMessageIn[0] << 8;
      *pUserIdOut |= pMessageIn[1];
    }

    pMessageIn += 2;
    if (pDirection != NULL)
    {
      *pDirection = *pMessageIn;
    }

    pMessageIn++;
    return true;
  }

  return false;
}

bool FaceReplyGetFeatureInformatizationMessage(const uint8_t *pMessageIn, uint32_t *pSizeOfFeatureOut)
{
  if (pMessageIn != NULL)
  {
    if (pSizeOfFeatureOut != NULL)
    {
      *pSizeOfFeatureOut = pMessageIn[0] << 24;
      *pSizeOfFeatureOut |= pMessageIn[1] << 16;
      *pSizeOfFeatureOut |= pMessageIn[2] << 8;
      *pSizeOfFeatureOut |= pMessageIn[3];
    }

    pMessageIn += 4;
    return true;
  }

  return false;
}

bool FaceReplyUploadFeatureDataMessage(const uint8_t *pMessageIn)
{
  return true;
}

bool FaceReplyEnrollFromFeatureMessage(const uint8_t *pMessageIn, uint16_t *pUserIdOut, uint8_t *pDirection)
{
  if (pMessageIn != NULL)
  {
    if (pUserIdOut != NULL)
    {
      *pUserIdOut = pMessageIn[0] << 8;
      *pUserIdOut |= pMessageIn[1];
    }

    pMessageIn += 2;
    if (pDirection != NULL)
    {
      *pDirection = *pMessageIn;
    }

    pMessageIn++;
    return true;
  }

  return false;
}

bool FaceReplyCapturePictureTypeMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplyGetsNumberOfAllRegisteredUsersMessage(const uint8_t *pMessageIn, uint16_t *pNumberOfUserOut)
{
  if (pMessageIn != NULL)
  {
    if (pNumberOfUserOut != NULL)
    {
      *pNumberOfUserOut = pMessageIn[0] << 8;
      *pNumberOfUserOut |= pMessageIn[1];
    }

    pMessageIn += 2;
    return true;
  }

  return false;
}

bool FaceReplyEnrollSingleMessage(const uint8_t *pMessageIn, uint16_t *pUserIdOut, uint8_t *pDirection)
{
  if ((pMessageIn != NULL) && (pUserIdOut != NULL) && (pDirection != NULL))
  {
    if (pUserIdOut != NULL)
    {
      *pUserIdOut = pMessageIn[0] << 8;
      *pUserIdOut |= pMessageIn[1];
    }

    pMessageIn += 2;
    if (pDirection != NULL)
    {
      *pDirection = *pMessageIn;
    }

    pMessageIn++;
    return true;
  }

  return false;
}

bool FaceReplySetThresholdLevelMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplyModulePowerDownMessage(const uint8_t *pDataIn)
{
  return true;
}

bool FaceReplyGetAlgorithmVersionMessage(const uint8_t *pMessageIn, char *pAlgorithmVersionOut)
{
  if (pMessageIn != NULL)
  {
    if (pAlgorithmVersionOut != NULL)
    {
      memcpy(pAlgorithmVersionOut, pMessageIn, FACE_LENGTH_OF_LIBRARY_VERSION);
    }

    pMessageIn += FACE_LENGTH_OF_LIBRARY_VERSION;
    return true;
  }

  return false;
}

bool FaceReplyIntoDemoModeMessage(const uint8_t *pDataIn)
{
  return true;
}

#elif (_FACE_MODULE_TYPE_ == _SENSETIME_FACE_MODEL_)
uint8_t FaceParityCheck(uint8_t *pDataIn, uint16_t DataSize)
{
  uint8_t CheckCode = pDataIn[0];

  for (uint16_t i = 1; i < DataSize; i++)
  {
    CheckCode ^= pDataIn[i];
  }

  return CheckCode;
}

bool FaceBuildHardwareSelfTestMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_HARDWARE_SELF_TEST_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildSoftwareResetMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_RESET_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildStartVerifyMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t Timeout)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_VERIFY_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = (uint8_t)((Timeout & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(Timeout & 0x00FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildCapturePictureMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t Counts, uint8_t StartNumber)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (StartNumber >= 1) && (StartNumber <= 30))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SNAP_IMAGE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = Counts;
    pMessageOut[MessageSize++] = StartNumber;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetCapturedPicturesMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t NumberOfPictures)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (NumberOfPictures >= 1) && (NumberOfPictures <= 30))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_SAVED_IMAGE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x01;
    pMessageOut[MessageSize++] = NumberOfPictures;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildUploadImageMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t ImageOffset, uint32_t ImageSize)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (ImageSize != 0) && (ImageSize <= FACE_MAX_FILE_REQUEST_SIZE))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_UOLOAD_IMAGE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x08;
    pMessageOut[MessageSize++] = (uint8_t)((ImageOffset & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((ImageOffset & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((ImageOffset & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(ImageOffset & 0x000000FF);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(ImageSize & 0x000000FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildEnrollSingleMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, bool Admin, uint8_t *pUserNameIn, uint8_t Timeout, uint8_t Direction)
{
  bool BuildResult = false;
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    switch (Direction)
    {
    case FACE_DIRECTION_UNDEFINE:
    case FACE_DIRECTION_MIDDLE:
    case FACE_DIRECTION_RIGHT:
    case FACE_DIRECTION_LEFT:
    case FACE_DIRECTION_DOWN:
    case FACE_DIRECTION_UP:
    {
      BuildResult = true;

      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_ENROLL_SINGLE_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = FACE_MAX_USER_NAME_LENGTH + 3;
      pMessageOut[MessageSize++] = Admin;
      (pUserNameIn != NULL) ? memcpy(&pMessageOut[MessageSize], pUserNameIn, FACE_MAX_USER_NAME_LENGTH) : memset(&pMessageOut[MessageSize], 0, FACE_MAX_USER_NAME_LENGTH);
      MessageSize += FACE_MAX_USER_NAME_LENGTH;
      pMessageOut[MessageSize++] = Direction;
      pMessageOut[MessageSize++] = Timeout;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
    }
    break;
    }
  }

  return BuildResult;
}

bool FaceBuildEnrollRGBImageMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, bool Admin, uint8_t *pUserNameIn, uint8_t Timeout, uint8_t Direction)
{
  bool BuildResult = false;
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    switch (Direction)
    {
    case FACE_DIRECTION_UP:
    case FACE_DIRECTION_DOWN:
    case FACE_DIRECTION_LEFT:
    case FACE_DIRECTION_RIGHT:
    case FACE_DIRECTION_MIDDLE:
    case FACE_DIRECTION_UNDEFINE:
    {
      BuildResult = true;

      pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
      pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
      pMessageOut[MessageSize++] = FACE_API_ENROLL_RGB_CMD;
      pMessageOut[MessageSize++] = 0x00;
      pMessageOut[MessageSize++] = FACE_MAX_USER_NAME_LENGTH + 3;
      pMessageOut[MessageSize++] = Admin;
      (pUserNameIn != NULL) ? memcpy(&pMessageOut[MessageSize], pUserNameIn, FACE_MAX_USER_NAME_LENGTH) : memset(&pMessageOut[MessageSize], 0, FACE_MAX_USER_NAME_LENGTH);
      MessageSize += FACE_MAX_USER_NAME_LENGTH;
      pMessageOut[MessageSize++] = Direction;
      pMessageOut[MessageSize++] = Timeout;
      pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

      *pSizeOut = MessageSize;
    }
    break;
    }
  }

  return BuildResult;
}

bool FaceBuildExampleDeleteSpecifiedUserMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t UserId)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_DEL_USER_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = (uint8_t)((UserId & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(UserId & 0x00FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildDeleteAllUserMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_DEL_ALL_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetUserInformationMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t UserId)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_USER_INFO_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = (uint8_t)((UserId & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(UserId & 0x00FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetAllUserIdMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_ALL_USER_ID_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetModuleVersionMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_VERSION_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildInitEncryptioMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t Radom, uint8_t Mode, uint32_t Timestamp)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_INIT_ENCRYPTION_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x09;
    pMessageOut[MessageSize++] = (uint8_t)((Radom & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((Radom & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((Radom & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(Radom & 0x000000FF);
    pMessageOut[MessageSize++] = Mode;
    pMessageOut[MessageSize++] = (uint8_t)((Timestamp & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((Timestamp & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((Timestamp & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(Timestamp & 0x000000FF);
    pMessageOut[MessageSize++] = 0;
    pMessageOut[MessageSize++] = 0;
    pMessageOut[MessageSize++] = 0;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildSetReleaseEncryptioKeyMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, const uint8_t *pKeyIn)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (pKeyIn != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SET_RELEASE_ENC_KEY_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x10;
    memcpy(pMessageOut + MessageSize, pKeyIn, 16);
    MessageSize += 16;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildSetRGBImageInformationMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t ImageSize)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SET_RGBIMAGE_SIZE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x04;
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0xFF000000) >> 24);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0x00FF0000) >> 16);
    pMessageOut[MessageSize++] = (uint8_t)((ImageSize & 0x0000FF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(ImageSize & 0x000000FF);
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildSetRGBImageDataMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint16_t ImageOffset, const uint8_t *pImageDataIn, uint16_t ImageDataSize)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SET_RGBIMAGE_SIZE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = ImageDataSize + 2;
    pMessageOut[MessageSize++] = (uint8_t)((ImageOffset & 0xFF00) >> 8);
    pMessageOut[MessageSize++] = (uint8_t)(ImageOffset & 0x00FF);
    memcpy(&pMessageOut[MessageSize], pImageDataIn, ImageDataSize);
    MessageSize += ImageDataSize;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildSetThresholdLevelMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint8_t Liveness, uint8_t Verify)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL) && (Liveness < 4) && (Verify < 4))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_SET_THRESHOLD_LEVEL_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x02;
    pMessageOut[MessageSize++] = Liveness;
    pMessageOut[MessageSize++] = Verify;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildModulePowerDownMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_POWER_DOWN_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}

bool FaceBuildGetAlgorithmVersionMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut!= NULL) && (pSizeOut!= NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_GET_LIBRARY_VERSION;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2); 
  }
}

bool FaceBuildIntoDemoModeMessage(uint8_t *pMessageOut, uint16_t *pSizeOut)
{
  uint16_t MessageSize = 0;

  if ((pMessageOut != NULL) && (pSizeOut != NULL))
  {
    pMessageOut[MessageSize++] = FACE_SYNCWORD_H_BYTE;
    pMessageOut[MessageSize++] = FACE_SYNCWORD_L_BYTE;
    pMessageOut[MessageSize++] = FACE_API_DEMO_MODE_CMD;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = 0x00;
    pMessageOut[MessageSize++] = FaceParityCheck(pMessageOut + 2, MessageSize - 2);

    *pSizeOut = MessageSize;
    return true;
  }

  return false;
}
#endif
#endif
